package cn.lingyangwl.agile.system.manager;

import cn.lingyangwl.agile.common.security.utils.SecurityUtils;
import cn.lingyangwl.agile.model.enums.RoleEnum;
import cn.lingyangwl.agile.system.mapper.SysUserMapper;
import cn.lingyangwl.agile.system.mapper.SysUserRoleMapper;
import cn.lingyangwl.agile.system.model.entity.SysUser;
import cn.lingyangwl.agile.system.model.entity.SysUserRole;
import cn.lingyangwl.agile.tenant.core.utils.TenantUtils;
import cn.lingyangwl.framework.mybatis.mate.annotations.FieldUniqueCheck;
import cn.lingyangwl.framework.mybatis.mate.enums.OperationTypeEnum;
import cn.lingyangwl.framework.tool.core.CollectionUtils;
import cn.lingyangwl.framework.tool.core.exception.BizException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author shenguangyang
 */
@Component
public class SysUserManager extends ServiceImpl<SysUserMapper, SysUser>
        implements IService<SysUser> {
    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysUserRoleMapper userRoleRelMapper;

    @FieldUniqueCheck(type = OperationTypeEnum.SAVE)
    public boolean saveUser(SysUser sysUser) {
        return sysUserMapper.insert(sysUser) > 0;
    }

    public List<Long> listUserIdsByRoleIds(List<Long> roleIds) {
        if (CollectionUtils.isEmpty(roleIds)) {
            return Collections.emptyList();
        }
        return userRoleRelMapper.selectList(SysUserRole.lqw().in(SysUserRole::getRoleId, roleIds))
                .stream().map(SysUserRole::getUserId).distinct().collect(Collectors.toList());
    }

    /**
     * 校验用户是否被允许操作, 如果在所有的租户中, 拥有任意一个租户(租户所有者, 一般为在某个用户下自行创建的用户), 则不允许被删除, 也不允许
     * 更新用户, 只能查看(租户所有者可以更新自己的)
     * @param userId 用户id
     */
    public void checkUserAllowed(Long userId) {
        if (Objects.isNull(userId)) {
            return;
        }

        Long loginUserId = SecurityUtils.getUserId();
        if (loginUserId.compareTo(userId) == 0) {
            return;
        }

        LambdaQueryWrapper<SysUserRole> lqw = SysUserRole.lqw().eq(SysUserRole::getUserId, userId)
                .eq(SysUserRole::getRoleCode, RoleEnum.OWNER.getCode());

        if (userRoleRelMapper.selectCount(lqw) > 0) {
            throw new BizException("不可操作租户拥有者");
        }
    }

    public void checkUserAllowed(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        TenantUtils.executeIgnore(() -> {
            LambdaQueryWrapper<SysUserRole> lqw = SysUserRole.lqw().eq(SysUserRole::getUserId, ids)
                    .eq(SysUserRole::getRoleCode, RoleEnum.OWNER.getCode());

            if (userRoleRelMapper.selectCount(lqw) > 0) {
                throw new BizException("不可操作租户拥有者");
            }
        });
    }

    /**
     * 获取当前租户拥有者的用户id
     */
    public Long getOwnerUserId() {
        LambdaQueryWrapper<SysUserRole> lqw = SysUserRole.lqw()
                .eq(SysUserRole::getRoleCode, RoleEnum.OWNER.getCode());
        return userRoleRelMapper.selectOne(lqw).getUserId();
    }
}
